﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace YYS
{
    [System.AttributeUsage(System.AttributeTargets.All, AllowMultiple = true)]
    public class Attr : System.Attribute
    {
        public Attr(string __display)
        {
            _display = __display;
        }

        private string _display = string.Empty;
        public string display { get { return _display; } set { _display = value; } }

        private int _maxLen = -1;
        public int maxLen { get { return _maxLen; } set { _maxLen = value; } }

        private int _minLen = -1;
        public int minLen { get { return _minLen; } set { _minLen = value; } }

        private object[] _customArr = new object[] { };
        public object[] customArr { get { return _customArr; } set { _customArr = value; } }

        public bool Required { get; set; }

        public bool isEmail { get; set; }

        public bool isNum { get; set; }

        public bool isPhone { get; set; }

        /// <summary>
        /// 是否手机号码
        /// </summary>
        public bool isMobie { get; set; }

        public bool isSmsTel { get; set; }

        public bool isDecimal { get; set; }

        public bool isInt { get; set; }


        int _EqualOrMoreThan = int.MinValue;
        public int EqualOrMoreThan
        {
            get { return _EqualOrMoreThan; }
            set { _EqualOrMoreThan = value; }
        }
        public string EqualOrMoreThanError { get; set; }
        int _moreThan = int.MinValue;
        /// <summary>
        /// 必须大于
        /// </summary>
        public int moreThan
        {
            get { return _moreThan; }
            set { _moreThan = value;}
        }
        public string moreThanError { get; set; }

        int _lessThan = int.MaxValue;
        public int lessThan
        {
            get { return _lessThan; }
            set { _lessThan = value; }
        }
        public string lessThanError { get; set; }

        public string strRegex { get; set; }
        /// <summary>
        /// 3-12位
        /// </summary>
        public bool isRegName { get; set; }
        /// <summary>
        /// 4-15位
        /// </summary>
        public bool isRegPwd { get; set; }

        /// <summary>
        /// 验证全部
        /// </summary>
        /// <param name="entityObject"></param>
        /// <returns></returns>
        public static string isValid(object entityObject)
        {
            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            System.Type type = entityObject.GetType();
            System.Reflection.PropertyInfo[] properties = type.GetProperties();
            foreach (System.Reflection.PropertyInfo property in properties)
            {
                if (property.CanRead)
                {
                    object[] validateContent = property.GetCustomAttributes(typeof(Attr), true);
                    if (validateContent != null && validateContent.Length > 0)
                    {
                        object value = property.GetValue(entityObject, null);
                        if (null == value) value = string.Empty;
                        foreach (Attr attr in validateContent)
                        {
                            sb.Append(valid(attr, attr.display, value));
                        }
                    }
                }
            }
            return sb.ToString().Trim().Length > 0 ? sb.ToString().Trim() : null;
        }

        /// <summary>
        /// 验证全部 不包含特定字段 成功返回 null
        /// </summary>
        /// <param name="entityObject"></param>
        /// <param name="notContainProperties"></param>
        /// <returns></returns>
        public static string isValid(object entityObject, params string[] notContainProperties)
        {
            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            System.Type type = entityObject.GetType();
            System.Reflection.PropertyInfo[] properties = type.GetProperties();
            foreach (System.Reflection.PropertyInfo property in properties)
            {
                if (!notContainProperties.Contains(property.Name) && property.CanRead)
                {
                    object[] validateContent = property.GetCustomAttributes(typeof(Attr), true);
                    if (validateContent != null && validateContent.Length > 0)
                    {
                        object value = property.GetValue(entityObject, null);
                        if (null == value) value = string.Empty;
                        foreach (Attr attr in validateContent)
                        {
                            sb.Append(valid(attr, attr.display, value));
                        }
                    }
                }
            }
            return sb.ToString().Trim().Length > 0 ? sb.ToString().Trim() : null;
        }

        /// <summary>
        /// 验证单个字段
        /// </summary>
        /// <param name="entityObject"></param>
        /// <param name="propertyName"></param>
        /// <returns></returns>
        public static string validField(object entityObject, string propertyName)
        {
            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            System.Type type = entityObject.GetType();
            var property = type.GetProperty(propertyName);
            if (property != null && property.CanRead)
            {
                object[] validateContent = property.GetCustomAttributes(typeof(Attr), true);
                if (validateContent != null && validateContent.Length > 0)
                {
                    object value = property.GetValue(entityObject, null);
                    if (null == value) value = string.Empty;
                    foreach (Attr attr in validateContent)
                    {
                        sb.Append(valid(attr, attr.display, value));
                    }
                }
            }
            return sb.ToString().Trim().Length > 0 ? sb.ToString().Trim() : null;
        }

        static string func(Attr attr, string name, object value)
        {
            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            if (attr.minLen > -1 && attr.maxLen > -1)
            {
                if (value.ToString().Trim().Length < attr.minLen || value.ToString().Trim().Length > attr.maxLen)
                {
                    sb.Append(string.Format("“{0}”长度为{1}-{2}位；", name, attr.minLen, attr.maxLen));
                }
            }
            else
            {
                if (attr.minLen > -1)
                {
                    if (value.ToString().Trim().Length < attr.minLen)
                    {
                        sb.Append(string.Format("“{0}”长度不能小于{1}；", name, attr.minLen));
                    }
                }
                if (attr.maxLen > -1)
                {
                    if (value.ToString().Trim().Length > attr.maxLen)
                    {
                        sb.Append(string.Format("“{0}”长度不能大于{1}；", name, attr.maxLen));
                    }
                }
            }
            if (attr.customArr.Length > 0)
            {
                if (!attr.customArr.Contains(value))
                {
                    sb.Append(string.Format("“{0}”不是预期的值；", name));
                }
            }
            if (attr.isEmail)
            {
                if (!new System.Text.RegularExpressions.Regex(@"\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*").Match(value.ToString().Trim()).Success)
                {
                    sb.Append(string.Format("“{0}”不是有效邮件格式；", name));
                }
            }

            if (attr._EqualOrMoreThan != decimal.MinValue && attr._EqualOrMoreThan > Utility.To<decimal>(value))
            {
                if (attr.EqualOrMoreThanError != null) { sb.Append(string.Format("“{0}”{1}；", name, attr.EqualOrMoreThanError)); }
                else { sb.Append(string.Format("“{0}”必须等于或大于{1}；", name, attr._EqualOrMoreThan)); }
            }

            if (attr.moreThan != int.MinValue && attr.moreThan >= Utility.To<int>(value))
            {
                sb.Append(string.Format("“{0}”{1}；", name, attr.moreThanError));
            }

            if (attr.lessThan != int.MaxValue && attr.lessThan <= Utility.To<int>(value))
            {
                sb.Append(string.Format("“{0}”{1}；", name, attr.lessThanError));
            }

            if (attr.isNum)
            {
                if (!new System.Text.RegularExpressions.Regex(@"^\d+$").Match(value.ToString().Trim()).Success)
                {
                    sb.Append(string.Format("“{0}”不是有效数字；", name));
                }
            }
            if (attr.isPhone)
            {
                if (!new System.Text.RegularExpressions.Regex(@"^((\d{11})|(((\d{3,4}\d{7,8})|(\d{3,4}-\d{7,8})|(\d{7,8}))(-\d{1,4})?))$").Match(value.ToString().Trim()).Success)
                {
                    sb.Append(string.Format("“{0}”不是有效电话号码格式；", name));
                }
            }
            if (attr.isMobie)
            {
                if (!value.ToString().jTrim().jMobileType().jRange(0,1,2))
                {
                    sb.Append(string.Format("“{0}”不是有效手机号码；", name));
                }
            }
            if (attr.isSmsTel)
            {
                if (Utility.getMobileType(value.ToString()) == -1)
                {
                    sb.Append(string.Format("“{0}”不是有效短信电话；", name));
                }
            }
            if (attr.isDecimal)
            {
                decimal f;
                if (!decimal.TryParse(value.ToString(), out f))
                {
                    sb.Append(string.Format("“{0}”不是有效浮点数；", name));
                }
            }
            if (attr.isInt)
            {
                int i;
                if (!int.TryParse(value.ToString(), out i))
                {
                    sb.Append("“" + name + "”不是有效数字；");
                }
            }
            if (attr.isRegName)
            {
                if (!new System.Text.RegularExpressions.Regex(@"^[a-zA-Z0-9_]{3,15}$").Match(value.ToString().Trim()).Success)
                {
                    sb.Append(string.Format("“{0}”长度为{1}-{2}位,且只能包含字母、数字或_；", name, 3, 15));
                }
            }
            if (attr.isRegPwd)
            {
                if (!new System.Text.RegularExpressions.Regex(@"^[a-zA-Z0-9_@#]{4,15}$").Match(value.ToString().Trim()).Success)
                {
                    sb.Append(string.Format("“{0}”长度为{1}-{2}位,且只能包含字母、数字、@或_；", name, 4, 15));
                }
            }
            if (!string.IsNullOrEmpty(attr.strRegex))
            {
                if (!new System.Text.RegularExpressions.Regex(attr.strRegex).Match(value.ToString().Trim()).Success)
                {
                    sb.Append(string.Format("“{0}”格式不正确；", name));
                }
            }
            return sb.ToString();
        }
        static string valid(Attr attr, string name, object value)
        {
            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            if (attr.Required)
            {
                if (null == value || value.ToString().Trim().Length < 1)
                {
                    sb.Append(string.Format("“{0}”不能为空；", name));
                }
                sb.Append(func(attr, name, value));
            }
            else if (null != value && value.ToString().Length > 0)
            {
                sb.Append(func(attr, name, value));
            }
            return sb.ToString();
        }

    }
}
